package com.appspot.categoryeditor.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;
import org.slim3.util.StringUtil;

import com.appspot.categoryeditor.meta.FolderMeta;
import com.appspot.categoryeditor.model.Category;
import com.appspot.categoryeditor.model.Folder;
import com.appspot.categoryeditor.model.User;
import com.appspot.categoryeditor.service.CategoryService;
import com.appspot.categoryeditor.utils.UrlUtils;
import com.appspot.categoryeditor.utils.UserUtils;
import com.appspot.categoryeditor.work.CreateSample;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class UserpageController extends Controller {

	private CategoryService categoryService = new CategoryService();
	private com.appspot.categoryeditor.service.UserService userService = new com.appspot.categoryeditor.service.UserService();

	final static FolderMeta FOLDER_META = FolderMeta.get();
	
	private final static String SAMPLE_USERID = "categoryeditor1";

	 private static final Log logger = LogFactory.getLog(UserpageController.class);
	
	private String userid;
	private String categoryid;
	
	private boolean onlyManagerMode = false;
	
	@Override
	public Navigation run() throws Exception {

		userid = asString("userid");
		categoryid = asString("categoryid");

		boolean isLogin = UserUtils.checkLogin(request);
		request.setAttribute("login", isLogin);
		
		String logginUserid = UserUtils.getLoginUserId();
		if (isLogin) {
			
			logger.debug("isLogin : " + isLogin  + "loggin userid : " + logginUserid);
			
			request.setAttribute("loginUserId", logginUserid);
			
			if(onlyManagerMode){
				logger.debug("onlyManagerMode : " + onlyManagerMode );
				if(!UserServiceFactory.getUserService().isUserAdmin()){
					response.setStatus(HttpServletResponse.SC_FORBIDDEN);
					return null;
				}
			}
			
		}

		boolean edditable = false;
		
		logger.debug("userid : " + userid);
		
		//指定リソースが本人の場合
		if (userid != null && userid.equals(logginUserid)) {
			logger.debug("edditable : " + edditable);
			edditable = true;

			// レコードが存在しなかった場合は初期データ作成
			if (!userService.checkUserExist(userid)) {
				logger.debug("user is not exist. creats new user data.");
				putSampleData();
				return redirect(UrlUtils.createUserPageUrl(userid, "sample"));
			}

		} else {
			if (userid == null 
					|| (!userid.equals(SAMPLE_USERID) && !userService.checkUserExist(userid)) ){
				logger.debug("url resource is not exist.");
				return redirect("/");
			} else {
				//admin権限がある場合常に編集可能
				if(isLogin && UserServiceFactory.getUserService().isUserAdmin()){
					logger.debug("edditable because current user is admin");
					edditable = true;
				}
				request.setAttribute("userid", userid);
			}
		}
		request.setAttribute("edditable", edditable);

		if (userid.equals(SAMPLE_USERID)) {
			logger.debug("sample data  show");
			request.setAttribute("sampleShow", true);
		}

		request.setAttribute("accessible", false);
		if (categoryid != null && !categoryid.equals("")) {
			Category category = categoryService.getCategory(userid, categoryid);
			if(category == null){
				return redirect(UrlUtils.createUserPageUrl(userid));
			}
			
			if (!edditable && !category.isAccessible()) {
				response.setStatus(HttpServletResponse.SC_FORBIDDEN);
				return null;
			}

			request.setAttribute("categoryid", categoryid);
			request.setAttribute("categoryName", category.getName());
			request.setAttribute("accessible", category.isAccessible());

			logger.debug("categoryid : " + categoryid);
			logger.debug("categoryName : " + category.getName());
			logger.debug("accessible : " + category.isAccessible() );

		}
		
		if(!StringUtil.isEmpty(asString("error"))){
			String errorVal = asString("error");
			if(errorVal.equals("jsonupload")){
				request.setAttribute("errormessage", 
						"JSONファイルのフォーマットが正しくありません。");
			}
		}
		return forward("/jsp/userpage.jsp");
	}

	private void putSampleData() {
		Transaction tx = Datastore.beginTransaction();
		try {
			User user = userService.addÜser(tx, userid);
			Folder folder = CreateSample.createSampleFolderModel(user
					.getId());
			categoryService.put(tx, folder);
			Category category = CreateSample
					.createSampleCategoryModel(user.getId(), folder);
			categoryService.put(tx, category);
			tx.commit();
		} finally{
			if (tx.isActive()) {
				tx.rollback();
			}
		}
	}

	protected static void redirectToLoginUrl(HttpServletRequest req,
			HttpServletResponse resp) {
		UserService userService = UserServiceFactory.getUserService();
		try {
			resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
		} catch (IOException e) {
		}
	}

}
